package com.haier.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haier.constant.Constant;
import com.haier.constant.HpConstant;
import com.haier.constant.URLConstant;
import com.haier.dto.HpGoApplyDto;
import com.haier.entity.*;
import com.haier.mapper.*;
import com.haier.service.IHpGoApplyService;
import com.haier.service.IJobService;
import com.haier.service.IhaierService;
import com.haier.utils.*;
import com.haier.vo.ApplyListVo;
import com.haier.vo.GardenVo;
import com.haier.vo.HpGoApplyVo;
import com.haier.vo.ResponseVo;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 通行申请 服务实现类
 * </p>
 *
 * @author luanxuecheng
 * @since 2020-07-01
 */
@Service
@Transactional(rollbackFor = Throwable.class)
public class HpGoApplyServiceImpl extends ServiceImpl<HpGoApplyMapper, HpGoApply> implements IHpGoApplyService {
	@Autowired
	private HpAreaGoCountMapper hpAreaGoCountMapper;
	@Autowired
	private HpAreaMapper hpAreaMapper;
	@Autowired
	private HpGardenMapper hpGardenMapper;
	@Autowired
	private IJobService iJobService;
	@Autowired
	private IhaierService ihaierService;
	@Autowired
	private HpAuthorizerConfigMapper hpAuthorizerConfigMapper;
	@Autowired
	private HpGoApplyDetailMapper hpGoApplyDetailMapper;
	@Autowired
	private HpAreaAuditorMapper hpAreaAuditorMapper;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public ResponseVo apply(List<ApplyListVo> params) throws Exception {
		// 获取入参信息
		String jobNumber = params.get(0).getJobNumber();
		String dateDay = params.get(0).getDateDay();
		List<ApplyListVo> newParams = new ArrayList<>();
		for (ApplyListVo vo : params) {
			// 判断申请人是否有该区域得免通行等级
			if(HpConstant.IS_AUDIT_YES.equals(vo.getIsAudit())){
				HpGoApply bean = new HpGoApply();
				bean.setAuditor(vo.getJobNumber());
				bean.setAuditorName(vo.getName());
				bean.setDateDay(dateDay);
				bean.setJobNumber(jobNumber);
				bean.setName(vo.getName());
				bean.setApplyReason(vo.getApplyReason());
				bean.setAreaId(vo.getAreaId());
				HpArea hpArea = hpAreaMapper.selectById(vo.getAreaId());
				bean.setGardenId(hpArea.getGardenId().toString());
				bean.setStatus(HpConstant.HP_GO_APPLY_STATUS_20);
				baseMapper.insert(bean);
				continue;
			}
			// 查询申请表查询该申请人同一时间内是否申请过该区域
			HpGoApplyDto dto = new HpGoApplyDto();
			dto.setAreaId((long)Integer.parseInt(vo.getAreaId()));
			dto.setJobNumber(jobNumber);
			dto.setDateDay(dateDay);
			dto.setStatus(HpConstant.HP_GO_APPLY_STATUS_10);
			HpGoApply hpGoApply = baseMapper.queryContainsAreaData(dto);
			// 如果有之前返回
			if (!EmptyUtils.isEmpty(hpGoApply)){
				StringBuffer prompt = new StringBuffer();
				List<HpArea> hpAreaList = hpAreaMapper.selectByIds(vo.getAreaId());
				prompt.append(hpAreaList.stream().map(HpArea::getName).collect(Collectors.toList())).append("  已在申请!");
				return ResponseVo.checkError(prompt.toString());
			}
			//过滤调不用申请得
			newParams.add(vo);
  		}
		// 将审核人一样的区域拼接
		Map<String, ApplyListVo> map = new HashMap();
		for (ApplyListVo p : newParams) {
			HpGoApplyDetail detail = new HpGoApplyDetail();
			detail.setAreaId(p.getAreaId());
			detail.setGoCount(p.getGoCount());
			detail.setCreateTime(new Date());
			hpGoApplyDetailMapper.insert(detail);
			//查询当前审核人有没有授权给别人
			QueryWrapper q = new QueryWrapper();
			q.eq("id",p.getAreaId());
			HpArea hpArea = hpAreaMapper.selectOne(q);
			String jobNum = "";
			// 根据goType查询  如果是固定审核人查询本地库
			if(HpConstant.GO_TYPE_THREE == hpArea.getGoType()){
				QueryWrapper qw = new QueryWrapper();
				qw.eq("area_id",p.getAreaId());
				HpAreaAuditor hpAreaAuditor = hpAreaAuditorMapper.selectOne(qw);
				jobNum = hpAreaAuditor.getJobNumber();
				// 否则调用第三方服务获取
			} else {
				JSONObject param = new JSONObject();
				param.put("userId", jobNumber);
				param.put("approverType", hpArea.getGoType());
				Map<String, String> header = new HashMap<String, String>();
				header.put("Authorization", getAuthorization());
				header.put("appKey", Constant.IHAIER_APP_KEY);
				String result = HttpUtils.post(URLConstant.IHAIER_APPROVER, param.toJSONString(), header);
				JSONObject resultJson = JSON.parseObject(result);
				String code = resultJson.getString("code");
				if (!"200".equals(code)) {
					return ResponseVo.checkError(resultJson.getString("msg"));
				}
				jobNum = resultJson.getString("object");
				if (EmptyUtils.isEmpty(jobNum)){
					return ResponseVo.checkError(resultJson.getString("msg"));
				}
			}
			p.setAuditor(jobNum);
			// 如果有则更新否存储
			if (!EmptyUtils.isEmpty(map.get(p.getAuditor()))) {
				p.setAreaId(map.get(p.getAuditor()).getAreaId() + "," + p.getAreaId());
				p.setDetailId(map.get(p.getAuditor()).getDetailId() + "," +detail.getId());
			}else{
				p.setDetailId(detail.getId().toString());
			}
			// 园区name
			List<HpArea> gardenList = hpAreaMapper.selectByIds(p.getAreaId());
			StringBuffer buffer = new StringBuffer();
			gardenList.forEach(garden ->{
				if (gardenList.size() -1 == gardenList.indexOf(garden)) {
					buffer.append(garden.getGardenId());
				} else {
					buffer.append(garden.getGardenId()).append(",");
				}

			});
			p.setGardenId(buffer.toString());
			map.put(p.getAuditor(), p);
		}
		// map转list
		params = new ArrayList<>(map.values());
		//遍历发送待办
		params.forEach(p -> {
			HpGoApply bean = new HpGoApply();
			QueryWrapper query = new QueryWrapper();
			query.eq("authorizer_num",p.getAuditor());
			query.eq("is_enable",HpConstant.ISENABLE_YES);
			HpAuthorizerConfig hpAuthorizerConfig = hpAuthorizerConfigMapper.selectOne(query);
			//如果被授权的话
			if(hpAuthorizerConfig!=null){
				p.setAuditor(hpAuthorizerConfig.getPassivityAuthorizerNum());
				p.setAuditorName(hpAuthorizerConfig.getPassivityAuthorizerName());
				bean.setAuthorizerId(hpAuthorizerConfig.getAuthorizerNum());//授权人工号
				bean.setAuthorizerName(hpAuthorizerConfig.getAuthorizerName());//授权人姓名
			}else{
				//如果没有授权给别人的话，授权人为审核人
				bean.setAuthorizerId(p.getAuditor());
				bean.setAuthorizerName(p.getAuditorName());
			}
			bean.setAuditor(p.getAuditor());
			bean.setAuditorName(p.getAuditorName());
			bean.setDateDay(dateDay);
			bean.setJobNumber(jobNumber);
			bean.setName(p.getName());
			bean.setDetailId(p.getDetailId());
			bean.setApplyReason(p.getApplyReason());
			bean.setAreaId(p.getAreaId());
			bean.setGardenId(p.getGardenId());
			bean.setGoCount(0);
			bean.setStatus(HpConstant.HP_GO_APPLY_STATUS_10);
			baseMapper.insert(bean);
			try {
				// 拼接待办信息
				Long id = bean.getId();
				StringBuffer title = new StringBuffer();
				List<HpArea> hpAreaList = hpAreaMapper.selectByIds(p.getAreaId());
				StringBuffer hpAreaId = new StringBuffer();
				for (HpArea area : hpAreaList) {
					if (hpAreaList.size() -1 == hpAreaList.indexOf(area)) {
						hpAreaId.append(area.getGardenId());
					} else {
						hpAreaId.append(area.getGardenId()).append(",");
					}
				}
				List<GardenVo> hpGardenList = hpGardenMapper.selectByIds(hpAreaId.toString());
				title.append("[HiPass] 待审核：").append(p.getName()).append(jobNumber);
				title.append(" 申请 ").append(dateDay).append(" 通行");
				Map<String, String> collect = hpGardenList.stream().collect(Collectors.toMap(GardenVo::getId, GardenVo::getName));
				String[] split = hpAreaId.toString().split(",");
				for (int i = 0; i < split.length; i++) {
					title.append("[").append(collect.get(split[i])).append("-").append(hpAreaList.get(i).getName()).append("]  ");
				}
				String taskId = Constant.JOB_SYSID + "_" + GetUtils.getIntString(GetUtils.getInt(id), 10);
				iJobService.begin(taskId, jobNumber, p.getAuditor(), title.toString(), id);
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
		return ResponseVo.success();
	}

	@SuppressWarnings("rawtypes")
	@Override
	public ListPageUtil<HpGoApplyVo> pageByH5(HpGoApplyDto dto) {
		List<HpGoApplyVo> applyList = baseMapper.selectByDto(dto);
		return ListPageUtil.startPage(equivalentSubstitution(applyList),dto.getPageNo(),dto.getPageSize());
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public ResponseVo setStatus(HpGoApplyDto dto) throws Exception {
		Long[] ids = dto.getIds();
		String auditor = dto.getAuditor();
		Integer status = dto.getStatus();

		if (EmptyUtils.isEmpty(ids)) {
			return ResponseVo.checkError("id不能为空");
		}

		List<String> taskIdList = new ArrayList<String>();
		for (Long id : ids) {
			HpGoApply hpGoApply = baseMapper.selectById(id);
			if (EmptyUtils.isEmpty(hpGoApply)) {
				return ResponseVo.checkError("id无效，请刷新列表再试");
			}
			if (!HpConstant.HP_GO_APPLY_STATUS_10.equals(hpGoApply.getStatus())) {
				return ResponseVo.checkError("申请状态无效，请刷新列表再试");
			}
			if (!hpGoApply.getAuditor().equalsIgnoreCase(auditor)) {
				return ResponseVo.checkError("工号无效");
			}
			hpGoApply.setStatus(status);
			baseMapper.updateById(hpGoApply);
			if(HpConstant.HP_GO_APPLY_STATUS_20.equals(status)){
				String[] detailId = hpGoApply.getDetailId().split(",");
				for (String s : detailId) {
					HpGoApplyDetail detail = hpGoApplyDetailMapper.selectById(s);
					String applyId = detail.getAreaId();
					QueryWrapper queryWrapper = new QueryWrapper();
					queryWrapper.eq("job_number", hpGoApply.getJobNumber());
					queryWrapper.eq("date_day", hpGoApply.getDateDay());
					queryWrapper.eq("area_id", applyId);
					HpAreaGoCount hpAreaGoCount = hpAreaGoCountMapper.selectOne(queryWrapper);

					if (hpAreaGoCount == null) {
						hpAreaGoCount = new HpAreaGoCount();
						hpAreaGoCount.setAreaId(applyId);
						hpAreaGoCount.setDateDay(hpGoApply.getDateDay());
						hpAreaGoCount.setJobNumber(hpGoApply.getJobNumber());
						hpAreaGoCount.setGoCount(detail.getGoCount());
						hpAreaGoCountMapper.insert(hpAreaGoCount);
					} else {
						hpAreaGoCount.setGoCount(hpAreaGoCount.getGoCount() + detail.getGoCount());
						hpAreaGoCountMapper.updateById(hpAreaGoCount);
					}
				}
			}
			String taskId = Constant.JOB_SYSID + "_" + GetUtils.getIntString(GetUtils.getInt(id), 10);
			taskIdList.add(taskId);
			iJobService.complete(taskIdList, auditor, status);
			}
		return ResponseVo.success();
	}

	@Override
	public ResponseVo getDetail(HpGoApplyDto dto) throws Exception {
		Long id = dto.getId();
		HpGoApply hpGoApply = baseMapper.selectById(id);

		JSONObject result = new JSONObject();
		result.put("id", hpGoApply.getId());
		result.put("jobNumber", hpGoApply.getJobNumber());
		result.put("name", hpGoApply.getName());
		result.put("auditor", hpGoApply.getAuditor());
		result.put("auditorName", hpGoApply.getAuditorName());
		result.put("dateDay", hpGoApply.getDateDay());
		result.put("applyReason", hpGoApply.getApplyReason());
		result.put("status", hpGoApply.getStatus());
		result.put("createTime", hpGoApply.getCreateTime());
		// 如果详情id为空则查询历史数据数量(单区域)
		if(EmptyUtils.isEmpty(hpGoApply.getDetailId())){
			HpArea hpArea = hpAreaMapper.selectById(hpGoApply.getAreaId());
			HpGarden hpGarden = hpGardenMapper.selectById(hpArea.getGardenId());
			result.put("area", hpArea.getName());
			result.put("garden", hpGarden.getName());
			result.put("goCount", hpGoApply.getGoCount());
		// 否则查询详情表数量
		}else{
			StringBuffer hpGardenId = new StringBuffer();
			// 区域
			List<HpArea> hpArea = hpAreaMapper.selectByIds(hpGoApply.getAreaId());
			// 数量
			List<String> goCountList = hpGoApplyDetailMapper.selectByIds(hpGoApply.getDetailId());
			for (HpArea area : hpArea) {
				if (hpArea.size() -1 == hpArea.indexOf(area)) {
					hpGardenId.append(area.getGardenId());
				} else {
					hpGardenId.append(area.getGardenId()).append(",");
				}
			}
			// 园区name
			List<GardenVo> gardenList = hpGardenMapper.selectByIds(hpGardenId.toString());
			Map<String, String> map = gardenList.stream().collect(Collectors.toMap(GardenVo::getId, GardenVo::getName));
			StringBuffer garden = new StringBuffer();
			String[] split = hpGardenId.toString().split(",");
			for (int i = 0; i < split.length; i++) {
				if(split.length-1 == i){
					garden.append(map.get(split[i]));
				}else{
					garden.append(map.get(split[i])).append(",");
				}
			}
			StringBuffer goCount = new StringBuffer();
			StringBuffer area = new StringBuffer();
			for (int i = 0; i < hpArea.size(); i++) {
				if(i == hpArea.size()-1){
					goCount.append(goCountList.get(hpArea.size()-(i+1)));
					area.append(hpArea.get(i).getName());
				} else {
					goCount.append(goCountList.get(hpArea.size()-(i+1))).append(",");
					area.append(hpArea.get(i).getName()).append(",");
				}
			}
			result.put("goCount",goCount);
			result.put("area",area);
			result.put("garden",garden);
		}
		/* 获取审核人信息 */
		JSONObject ihaierInfo = ihaierService.getUserInfo(hpGoApply.getAuditor());
		result.put("auditorEmail", ihaierInfo.getString("haierMail"));
		result.put("auditorMobile", ihaierInfo.getString("phone"));

		result.put("proposerStatusDetail", HpConstant.HP_GO_APPLY_PROPOSER_STATUS_MAP.get(hpGoApply.getStatus()));
		result.put("auditorStatusDetail", HpConstant.HP_GO_APPLY_AUDITOR_STATUS_MAP.get(hpGoApply.getStatus()));

		return ResponseVo.success(result);
	}

	/**
	 * 导出excel
	 * @param dto
	 * @return
	 */
	@Override
	public SXSSFWorkbook reportApply(HpGoApplyDto dto) {
		//查询申请列表
		List<HpGoApplyVo> list = baseMapper.pageByH5(dto);

		SXSSFWorkbook book = new SXSSFWorkbook();
		Sheet sheet = book.createSheet("申请列表");
		Row row = sheet.createRow(0);
		CellStyle style = book.createCellStyle();
		Font font = book.createFont();
		font.setFontName("宋体");
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);// 粗体
		style.setFont(font);
		Cell cell = row.createCell(0);
		row.createCell(0).setCellValue("申请人工号");
		row.createCell(1).setCellValue("申请人");
		row.createCell(2).setCellValue("审核人");
		row.createCell(3).setCellValue("园区");
		row.createCell(4).setCellValue("区域");
		row.createCell(5).setCellValue("通行次数");
		row.createCell(6).setCellValue("申请理由");
		row.createCell(7).setCellValue("申请通行时间");
		row.createCell(8).setCellValue("创建时间");
		row.createCell(9).setCellValue("审核状态");
		for (int i = 0; i < 10; i++) {
			cell = row.getCell(i);
			cell.setCellStyle(style);
		}

		if (EmptyUtils.isEmpty(list)) {
			return book;
		}
		Iterator<HpGoApplyVo> it = list.iterator();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		int i = 1;
		while (it.hasNext()) {
			HpGoApplyVo hpGoApplyVo = it.next();
			row = sheet.createRow(i++);
			row.createCell(0).setCellValue(GetUtils.getString(hpGoApplyVo.getProposerNo()));//申请人工号
			row.createCell(1).setCellValue(GetUtils.getString(hpGoApplyVo.getProposer()));//申请人
			row.createCell(2).setCellValue(GetUtils.getString(hpGoApplyVo.getAuditor()));//审核人
			row.createCell(3).setCellValue(GetUtils.getString(hpGoApplyVo.getGarden()));//园区
			row.createCell(4).setCellValue(GetUtils.getString(hpGoApplyVo.getArea()));//区域
			row.createCell(5).setCellValue(GetUtils.getString(hpGoApplyVo.getGoCount()));//通行次数
			row.createCell(6).setCellValue(GetUtils.getString(hpGoApplyVo.getApplyReason()));//申请理由
			row.createCell(7).setCellValue(GetUtils.getString(hpGoApplyVo.getDateDay()));//申请通行时间
			String dateString = formatter.format(hpGoApplyVo.getCreateTime());
			row.createCell(8).setCellValue(dateString);//创建时间
			String status = HpConstant.HP_GO_APPLY_PROPOSER_STATUS_MAP.get(hpGoApplyVo.getStatus());
			row.createCell(9).setCellValue(GetUtils.getString(status));//审核状态
		}
		return book;
	}

	/**
	 * 查看申请列表
	 * @param dto
	 * @return
	 */
	@Override
	public List<HpGoApplyVo> getListReport(HpGoApplyDto dto) {
		List<HpGoApplyVo> list = baseMapper.selectByDto(dto);
		return equivalentSubstitution(list);
	}

	/**
	 * 等值替换(园区,区域,数量)
	 * @param list
	 * @return
	 */
	public List<HpGoApplyVo> equivalentSubstitution(List<HpGoApplyVo> list){
		list.forEach(p->{
			StringBuffer hpGardenId = new StringBuffer();
			// 区域
			List<HpArea> hpArea = hpAreaMapper.selectByIds(p.getAreaId());
			for (HpArea area : hpArea) {
				if (hpArea.size() -1 == hpArea.indexOf(area)) {
					hpGardenId.append(area.getGardenId());
				} else {
					hpGardenId.append(area.getGardenId()).append(",");
				}
			}
			StringBuffer area = new StringBuffer();
			for (int i = 0; i < hpArea.size(); i++) {
				if(i == hpArea.size()-1){
					area.append(hpArea.get(i).getName());
				} else {
					area.append(hpArea.get(i).getName()).append(",");
				}
			}
			// 园区name
			List<GardenVo> gardenList = hpGardenMapper.selectByIds(hpGardenId.toString());
			Map<String, String> collect = gardenList.stream().collect(Collectors.toMap(GardenVo::getId, GardenVo::getName));
			StringBuffer garden = new StringBuffer();
			String[] split = hpGardenId.toString().split(",");
			for (int i = 0; i < split.length; i++) {
				if(split.length-1 == i){
					garden.append(collect.get(split[i]));
				}else{
					garden.append(collect.get(split[i])).append(",");
				}
			}
			if(!EmptyUtils.isEmpty(p.getDetailId())){
				// 数量
				List<String> goCountList = hpGoApplyDetailMapper.selectByIds(p.getDetailId());
				StringBuffer goCount = new StringBuffer();
				for (int i = 0; i < hpArea.size(); i++) {
					if(i == hpArea.size()-1){
						goCount.append(goCountList.get(hpArea.size()-(i+1)));
					} else {
						goCount.append(goCountList.get(hpArea.size()-(i+1))).append(",");
					}
				}
				p.setGoCount(goCount.toString());
			}
			p.setArea(area.toString());
			p.setGarden(garden.toString());
		});
		return list;
	}

	private String getAuthorization() throws Exception {
		Date date = new Date();
		String dateStr = GetUtils.getDateString(date, "yyyy-MM-dd");
		String mdfive = Constant.IHAIER_APP_SECRET + dateStr;
		return Md5Util.md5(mdfive);
	}
}
